using COC.Debug;
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using COC.Tool;
//using log4net;

namespace COC.Content
{
    /// <summary>
    /// responsibility of load resource(prefab) into a expected scene.
    /// </summary>
		public class LoaderManager : MonoBehaviour
		{
		//private static ILog LOGGER = LogManager.GetLogger(typeof(LoaderManager));

		private static LoaderManager instance;

		        [Obsolete("do not use new keyword when extends MonoBehaviour")]
				public static LoaderManager getInstance ()
				{
						if (instance == null) {
								instance = new LoaderManager ();
						}
						return instance;
				}
	
				/// <summary>
				/// whether exist  fresh script in remote server or not.If so,then update this script.若有脚本更新，则更新指定脚本
				/// </summary>
				/// <returns>The script.</returns>
				/// <param name="BundleURL">Bundle UR.</param>
				/// <param name="Path">Path.</param>
				/// <param name="Type">Type.</param>
				/// <param name="Version">Version.</param>
		public IEnumerator UpdateScript (string BundleURL, string Path,string PrefabName,LoadResourceType Type, int Version)
				{
			yield return LoadAsset (BundleURL, Path, Type,PrefabName, false, null, true, 0, null, Version);
				}

				/// <summary>
				/// 载入脚本到游戏对象game object上Adds the script in game object.
				/// </summary>
				/// <returns>The script in game object.</returns>
				/// <param name="BundleURL">Bundle UR.</param>
				/// <param name="Path">Path.</param>
				/// <param name="Type">Type.</param>
				/// <param name="LoadAll">If set to <c>true</c> load all.</param>
				/// <param name="Version">Version.</param>
		public IEnumerator AddScriptInGameObject (string BundleURL, string Path,string PrefabName, LoadResourceType Type, int Version)
				{
			yield return LoadAsset (BundleURL, Path, Type,PrefabName, false, null, true, 0, null, Version);
				}
				/// <summary>
				/// 通过场景方式加载资源
				/// </summary>
				/// <returns>The BY scene.</returns>
				/// <param name="BundleURL">Bundle UR.</param>
				/// <param name="Path">Path.</param>
				/// <param name="Type">Type.</param>
				/// <param name="Params">Parameters.</param>
				/// <param name="WhetherGameObject">If set to <c>true</c> whether game object.</param>
				/// <param name="Level">Level.</param>
				/// <param name="SceneName">Scene name.</param>
				/// <param name="Version">Version.</param>
		public IEnumerator LoadAssetBYScene (string BundleURL, string Path, string PrefabName,LoadResourceType Type, List<CTuple<string,string,int>> Params, bool WhetherGameObject, int Level, string SceneName, int Version)
				{
			yield return LoadAsset (BundleURL, Path, Type, PrefabName,false, Params, WhetherGameObject, Level, SceneName, Version);
				}
    

				/// <summary>
				/// 载入部分资源到场景中
				/// </summary>
				/// <returns>The partital.</returns>
				/// <param name="BundleURL">Bundle UR.</param>
				/// <param name="path">Path.</param>
				/// <param name="type">Type.</param>
				/// <param name="Params">Parameters.</param>
				/// <param name="whetherGameObject">If set to <c>true</c> whether game object.</param>
				/// <param name="level">Level.</param>
				/// <param name="sceneName">Scene name.</param>
				/// <param name="version">Version.</param>
		public IEnumerator LoadPartital (string BundleURL, string path, string PrefabName,LoadResourceType type, List<CTuple<string,string,int>> Params, bool whetherGameObject, int level, string sceneName, int version)
				{
			yield return LoadAsset (BundleURL, path, type, PrefabName,false, Params, whetherGameObject, level, sceneName, version);
				}




				/// <summary>
				/// </summary>
				/// <param name="BundleURL">网络地址</param>
				/// <param name="path">Asset路径+"/"+文件名称+"."+后缀名+</param>
				/// <param name="type">文件类型.</param>
				/// <param name="loadAll">是否全部载入If set to <c>true</c> load all.</param>
				/// <param name="Params">部分载入文件{"包名称1","包名称2"}</param>
				/// <param name="level">Level.场景ID</param>
				/// <param name="sceneName">场景名称</param>
				/// <param name="version">Version版本号.</param>
				/// 
		public	IEnumerator LoadAsset (string BundleURL, string Path, LoadResourceType Type,string PrefabName, bool LoadAll, List<CTuple<string,string,int>> Params, bool WhetherGameObject, int Level, string SceneName, int Version)
				{
		

						//string PrefabName = "";
		
						// WWW www = new WWW(BundleURL);
		
						//   yield return www;
						if (BundleURL.IndexOf ("unity3d") > 0) {
								//  GameObject go = new GameObject();
								//不同平台下StreamingAssets的路径是不同的，这里需要注意一下。
			
								string PathURL =
				
				#if UNITY_ANDROID
				
				"jar:file://" + Application.dataPath + "!/assets/";
			
			#elif UNITY_IPHONE
			
			Application.dataPath + "/Raw/";
			
			#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
			
			"file://" + Application.dataPath + "/StreamingAssets/";
			
			#else
			string.Empty;
								#endif
								// Wait for the Caching system to be ready
								while (!Caching.ready)
										yield return null;
			
								// Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
								using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, Version)) {

										yield return www;
										if (www.error != null){
						throw new System.Exception ("下载模型时发生错误:"+www.error);
					                       // Debug.LogError("下载模型时发生错误:"+www.error);
						                  }
					            AssetBundle bundle = www.assetBundle;
										if (PrefabName == "") {
												if (bundle.mainAsset != null)
														Instantiate (bundle.mainAsset);
										} else {
//					Debug.Log ("加载模型");
//					foreach (UnityEngine.Object go2 in bundle.LoadAll()) {
//						Instantiate (go2);



						
												//					if(Params!=null&&Params.Count>0){
												//
												//
												//
												//
												//
												//
												//					}else{

						DebugTool.Log("Type:="+Type);
					
											yield return DoLoading (PrefabName, bundle, Type, LoadAll);
					
												// GameObject obj = request.asset as GameObject;
												// yield return  
										}
										//	else
										//		Instantiate (bundle.Load (PrefabName));
										// Unload the AssetBundles compressed contents to conserve memory
										bundle.Unload (false);
				
										// Debug.Log("www done:" + www.text);
								} // memory is freed from the web stream (www.Dispose() gets called implicitly)
			
						}
		
				}

				private IEnumerator DoLoading (string PrefabName, AssetBundle bundle, LoadResourceType Type, bool loadAll)
				{

						//according to asset name 

						if (Type.Equals(LoadResourceType.DEFAULT)) {
                            DebugTool.Log("Starting.........");
								if (loadAll) {

										object[] objs = bundle.LoadAll (typeof(GameObject));
										foreach (object o in objs) {
												GameObject go = o as GameObject;
												Instantiate (go);
										}
								} else {
				
										Instantiate (bundle.Load (PrefabName) as GameObject);
								}
							//	yield return bundle;
						}else{

						//according to type 
                            DebugTool.Log("开始读取prefab");
						Type _type = typeof(GameObject);
						switch ((int)Type) {
						case (int)LoadResourceType.GAMEOBJECT:
								_type = typeof(GameObject);
								break;
						//case (int)LoadResourceType.PREFAB:
						//	break;
						default:
								break;
						}
						if (loadAll) {

								object[] objs = bundle.LoadAll (_type);
								foreach (object o in objs) {
										switch ((int)Type) {
										case (int)LoadResourceType.GAMEOBJECT:
												GameObject go = o as GameObject;
												Instantiate (go);
												break;

										//case (int)LoadResourceType.PREFAB:
										//	break;
										default:
												break;
										}	

								}

						} else {
								AssetBundleRequest request = bundle.LoadAsync (PrefabName, _type);
								yield return request;
								//foreach (UnityEngine.Object go2 in bundle.LoadAll()) {
								//	Instantiate (go2);
								//}
                                DebugTool.Log("Loading game object model");
								GameObject obj = request.asset as GameObject;
								Instantiate (obj);
						}
			}
						yield	return bundle;
				}
		}

}